/**
 * fshows.com
 * Copyright (C) 2013-2022 All Rights Reserved.
 */
package com.fshows.leshuapay.sdk.client.impl;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fshows.leshuapay.sdk.client.LeshuaGoldActivitySignClient;
import com.fshows.leshuapay.sdk.exception.LeshuaException;
import com.fshows.leshuapay.sdk.request.LeshuaBizRequest;
import com.fshows.leshuapay.sdk.response.LeshuaBaseResponse;
import com.fshows.leshuapay.sdk.util.SignUtil;
import com.fshows.leshuapay.sdk.util.StringPool;
import com.fshows.leshuapay.sdk.util.ValidateUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * 乐刷活动报名
 *
 * @author zhangmj
 * @version LeshuaActivitySignClient.java, v 0.1 2022-03-08 下午9:24 zhangmj
 */
@Slf4j
@Data
public class LeshuaGoldActivitySignClientImpl implements LeshuaGoldActivitySignClient {

    /**
     * 从connectManager获取Connection 超时时间
     */
    private static final int CONNECTION_REQUEST_TIMEOUT = 10000;

    /**
     * 读取数据的超时时间
     */
    private static final int SOCKET_TIMEOUT = 10000;

    /**
     * 连接超时时间
     */
    private static final int CONNECT_TIMEOUT = 10000;

    /**
     * 版本号
     */
    private static final String VERSION = "1.0";

    private static CloseableHttpClient httpclient = HttpClients.createDefault();

    /**
     * 服务商编号
     */
    private String agentId;

    /**
     * 服务商私钥
     */
    private String privateKey;

    /**
     * 调用地址
     */
    private String serverUrl;

    /**
     * 请求超时时间，单位毫秒
     */
    private Integer timeout;

    public LeshuaGoldActivitySignClientImpl(String agentId, String privateKey, String serverUrl, Integer timeout) {
        this.agentId = agentId;
        this.privateKey = privateKey;
        this.serverUrl = serverUrl;
        this.timeout = timeout;
    }

    /**
     * 支付宝团餐活动报名
     *
     * @param request
     * @param <T>
     * @return
     */
    @Override
    public <T> LeshuaBaseResponse<T> execute(LeshuaBizRequest<T> request, String url) throws Exception {
        //1、参数验证
        ValidateUtil.validateWithThrow(request);
        //2、参数构建
        RequestConfig requestConfig = null;
        if (timeout == null || timeout <= 0) {
            requestConfig = RequestConfig.custom().setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                    .setSocketTimeout(SOCKET_TIMEOUT).setConnectTimeout(CONNECT_TIMEOUT).build();
        } else {
            requestConfig = RequestConfig.custom().setConnectionRequestTimeout(timeout)
                    .setSocketTimeout(timeout).setConnectTimeout(timeout).build();
        }

        HttpPost httpPost = new HttpPost(serverUrl + url);
        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", StringPool.JSON_CONTENT_TYPE);
        httpPost.setEntity(new StringEntity(JSON.toJSONString(request), StandardCharsets.UTF_8));

        CloseableHttpResponse httpResponse = null;
        HttpEntity resEntity = null;
        try {
            httpResponse = httpclient.execute(httpPost);
            resEntity = httpResponse.getEntity();
            String responseStr = EntityUtils.toString(resEntity, SignUtil.DEFAULT_CHARSET);
            log.info("乐刷活动报名_乐刷接口请求返回 param={}; response={}", JSON.toJSONString(request), responseStr);
            LeshuaBaseResponse<T> response = new LeshuaBaseResponse<>();
            JSONObject jsonObject = JSON.parseObject(responseStr);
            response.setRespCode(jsonObject.getString("respCode"));
            response.setRespMsg(jsonObject.getString("respMsg"));
            String data = jsonObject.getString("data");
            if (StringUtils.isNotEmpty(data)) {
                response.setData(JSON.parseObject(data, request.getResponseClass()));
            }
            log.info("乐刷活动报名_请求乐刷接口入参:{} 乐刷活动报名_请求乐刷接口返回参数:{}", JSON.toJSONString(request), response);
            return response;
        } catch (Exception e) {
            log.error("乐刷活动报名_调用失败 param={} e={}", JSON.toJSONString(httpPost), ExceptionUtil.getSimpleMessage(e));
            throw new LeshuaException("乐刷活动报名_调用失败", e);
        } finally {
            try {
                EntityUtils.consume(resEntity);
            } catch (IOException e) {
                log.error("释放HttpEntity出错，错误信息：" + e.getMessage(), e);
            }
            if (httpResponse != null) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    log.error("关闭HttpResponse出错，错误信息：" + e.getMessage(), e);
                }
            }
        }
    }
}